#if !defined(ximera_physics_ode_world_hpp)
#define ximera_physics_ode_world_hpp

// -----------------------------------------------------------

#include <ximera/physics/iworld.hpp>
#include <ximera/physics/ode/ode.hpp>
#include <ximera/physics/ode/space.hpp>
#include <ximera/common/sharedptr.hpp>

#include <vector>

namespace ximera { namespace physics { namespace ode
{
	class XIMERA_PLUGIN_API World : public IWorld
    {
    public:
        World();
        virtual ~World();

        virtual math::Vector3 gravity() const;
        virtual void gravity(math::Vector3 const& value);

        virtual ISpace* createSpace(SpaceType type = SpaceType::Simple);
        
        virtual ISpace* space() const;
        virtual ISpace* space(UInt32 index) const;
        virtual UInt32 spaceCount() const;

        virtual StepType stepType() const;
        virtual void stepType(StepType value);

        virtual void step(Real secs);

        dWorldID worldID() const { return _worldID; }        
	
	private:
        typedef std::vector<SharedPtr<Space> > SpaceContainer;

        dWorldID _worldID;
        dJointGroupID _contactGroup;
        SpaceContainer _spaces;
        StepType _stepType;
        Real _timeStep;

    private:
        void collide(dGeomID geom1, dGeomID geom2);
        void collide(dGeomID geom1, dBodyID body1, dGeomID geom2, dBodyID body2);

        friend void collideCallback(void* data, dGeomID geom1, dGeomID geom2);
    };
}}}

// -----------------------------------------------------------

#endif
